#pragma once
#include <Windows.h>
#include <stdio.h>
#include <tchar.h>
#include "TempleteFea.h"
#include "utilfun.h"
#include "utilio.h"
#include <iostream>
#include "binstore.h"
#include "map_int.h"


struct zero_feature_link
{
	span_feature*	cur_span;
	zero_feature_link* next;
};

class grid_node0
{
public:
	int			  tag_id;
	zero_feature_link* node_feas;
	double		  grid_alpha;
	double		  grid_beta;

	inline void push_feas(freelist<char>& pool,span_feature* spn)
	{
		zero_feature_link* link = (zero_feature_link*)pool.alloc(sizeof(zero_feature_link));
		link->cur_span  = spn;
		link->next = node_feas;
		node_feas = link;
	}

	inline void init() {
		tag_id=0; node_feas = 0; grid_alpha = -1; grid_beta = -1;
	}
};

class crfHolder0
{
public:
	crfHolder0() { _map_pool.set_size(1024*37*37);_link_pool.set_size(1024*37*37);}

	freelist<char>	   _map_pool;
	freelist<char>	   _link_pool;
	double	_obj;
	double*	_lambda;
	double*	_gradient;
	double  _allZ;
	
	int					_tag_size;
	vector<map_int>		_tagid2gridid;

	vector<grid_node0*>	_node_grid;
	memPool<grid_node0>	_grid_memPool;

	vector<int*>		_grid_backtrack;
	memPool<int>		_backtrack_memPool;

	double*	_alpha;
	double* _beta;
	memPool<double>	    _double_pool;
	int					_tag_sentence_begin;

	memPool<char>		_decode_memPool;


	void build_lattice(sentence& sen);

	void calculate_alpha(sentence& sen);

	double calculate_cost(sentence& sen);
 
	void calculate_gradient(sentence& sen,double& z_all);

	double process_sen(sentence& sen);

	double decode(sentence& sen,vector< vector<int> >& predict_label,vector< vector<double> >& predict_prob);

	double process_decode(sentence& sen,vector< vector<int> >& predict_label,vector< vector<double> >& predict_prob);
};